12. Edge Case: Capturing Variables
Edge Case: Capturing Variables
ND079 JPND C2 L01 A09 Edge Case Capturing Variables V2
Captured Variables
Lambdas can capture variables from the surrounding code. If a lambda uses any variables from the surrounding code, those variables are captured. Variables can only be captured if they are effectively final.
An effectively final variable is a variable whose value does not change after it is initialized.
Example
Map<Year, Integer> getClassSizes(List<Student> students) {
final Map<Year, Integer> classSizes = new HashMap<>();
students.stream().forEach(s ->
classSizes.compute(
s.getGraduationYear(),
(k, v) -> (v == null) ? 1 : 1 + v));
return classSizes;
}
A good test to figure out if a variable is effectively final is to add the final
keyword to it. If the code still compiles, that variable is effectively final!
In the example, the classSizes
variable is effectively final because the value of the variable itself does not change after it's initialized. Remember that in Java, objects are passed by reference. Even though the HashMap
changes, the variable's value is the HashMap
's location in memory, and that location never changes.
SOLUTION:
- The value of the variable is never changed after it's first initialized.
- If you add the `final` keyword to the variable, the code will still compile.
void printResult(List<String> input, StringWriter output) {
Map<Integer, String> bySize = new HashMap<>();
input.stream().forEach(
(String s) -> bySize.put(s.length(), s));
output.write(generateSummary(bySize));
}
SOLUTION:
- `bySize`
List<Runnable> runnables = new ArrayList<>(10);
for (int i = 0; i < 10; i++) {
runnables.add(() -> System.out.println(i));
}